package de.rj.urwalking.ui.fragments;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ProgressBar;

import com.actionbarsherlock.app.SherlockFragment;
import com.threed.jpct.SimpleVector;

import de.rj.urwalking.R;
import de.rj.urwalking.interfaces.ControllableFragment;
import de.rj.urwalking.ui.BaseRenderer;
import de.rj.urwalking.ui.CompassView;
import de.rj.urwalking.ui.activities.URwalkingActivity;
import de.rj.urwalking.util.MultisampleConfigChooser;
import de.rj.urwalking.util.PrefUtil;

/**
 * Contains everything that is needed for 3d rendering both indoor and outdoor.
 * 
 * @author rjj
 * 
 */

public abstract class JpctFragment extends SherlockFragment implements OnDoubleTapListener, OnGestureListener,
		OnScaleGestureListener, OnTouchListener, ControllableFragment, BaseRenderer.Callbacks {

	protected BaseRenderer renderer;
	protected GLSurfaceView mGLView;

	protected ScaleGestureDetector scaleGestureDetector;
	protected GestureDetector gestureDetector;

	private SimpleVector[] cameraVectors;

	
	protected URwalkingActivity mActivity;
	protected CompassView mCompassView;
	protected ProgressBar mLoaderProgressBar;

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);

		try {
			mActivity = (URwalkingActivity) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException("this fragment can only be used inside URwalkingActivity!");
		}
	}
	
	@Override
	public void onPause() {
		super.onPause();
		mGLView.onPause();
		cameraVectors = renderer.getCameraVectors();


	}
	
	@Override
	public void onResume() {
		super.onResume();
		mGLView.onResume();

		if (cameraVectors != null) {
			renderer.setCameraVectors(cameraVectors);
		}
	}

	protected boolean handleButtonLeft(MotionEvent event) {
		((URwalkingActivity) getActivity()).disableGpsFollowing(false);

		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_MOVE:
			renderer.moveLeft();
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			renderer.stopMovingLeft();
			break;

		}
		return true;
	}

	protected boolean handleButtonRight(MotionEvent event) {
		((URwalkingActivity) getActivity()).disableGpsFollowing(false);

		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_MOVE:
			renderer.moveRight();
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			renderer.stopMovingRight();
			break;
		}
		return true;
	}

	protected boolean handleButtonForward(MotionEvent event) {
		((URwalkingActivity) getActivity()).disableGpsFollowing(false);

		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_MOVE:
			renderer.moveForward();
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			renderer.stopMovingForward();
			break;
		}
		return true;
	}

	protected boolean handleButtonBackward(MotionEvent event) {
		((URwalkingActivity) getActivity()).disableGpsFollowing(false);

		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_MOVE:
			renderer.moveBackward();
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			renderer.stopMovingBackward();
			break;
		}
		return true;
	}

	protected void initUI(View rootView) {
		setupGLSurfaceView(rootView);
		mCompassView = (CompassView) rootView.findViewById(R.id.compassView);
		mLoaderProgressBar = (ProgressBar) rootView.findViewById(R.id.runningLoaderProgressBar);
		setupControls(rootView);

	}
	
	private void setupGLSurfaceView(View rootView) {

		mGLView = (GLSurfaceView) rootView.findViewById(R.id.surfaceView);
		mGLView.setEGLContextClientVersion(2);

		if (PrefUtil.readBoolean(R.string.key_pref_graphics, getActivity(), false)) {
			// enable antialiasing and 24 bit color depth
			mGLView.setEGLConfigChooser(new MultisampleConfigChooser(MultisampleConfigChooser.RGB888));
		} else {
			// no aa, but at least enable dithering to avoid color banding
			com.threed.jpct.Config.glDither = true;

		}

		gestureDetector = new GestureDetector(getActivity(), this); 
		scaleGestureDetector = new ScaleGestureDetector(getActivity(), this);		
		mGLView.setOnTouchListener(this);
		
	}
	

	protected void showLoadingIndicator() {
		mLoaderProgressBar.setVisibility(View.VISIBLE);
	}

	protected void hideLoadingIndicator() {
		mLoaderProgressBar.setVisibility(View.INVISIBLE);
	}

	void setupControls(View rootView) {
		rootView.findViewById(R.id.buttonLeft).setOnTouchListener(this);
		rootView.findViewById(R.id.buttonRight).setOnTouchListener(this);
		rootView.findViewById(R.id.buttonForward).setOnTouchListener(this);
		rootView.findViewById(R.id.buttonBackward).setOnTouchListener(this);

	}
	
	// lots of unused callback methods following...
	
	@Override
	public boolean onDoubleTap(MotionEvent e) {
		return false;
	}

	@Override
	public boolean onDoubleTapEvent(MotionEvent e) {
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {

	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

}
